home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / combox.exe / COMBO.PAS < prev    next >
Pascal/Delphi Source File  |  1992-12-24  |  8KB  |  313 lines

  1. Unit Combo;
  2. interface
  3. uses Views, Objects, Drivers, Dialogs, StdDlg, Dos;
  4. {
  5.   Author: Keith Greer
  6.           68 Tamworth Rd.
  7.           Troy, OH  45373-1551
  8.  
  9.   C'Serve ID: 73457,3042
  10.     Internet: greerk@wpdis11.hq.aflc.af.mil
  11.  
  12.   This unit defines a "combo box" pull down selection list ala Windows.
  13.   The combo box looks and works similar to the history list. The
  14.   difference is, the history window only contains a limited number of
  15.   strings you have previously typed in the linked input line, whereas
  16.   the combo box displays a sorted collection and supports "power
  17.   typing" like TFileDialog.
  18.  
  19. }
  20.  
  21. const
  22.   cmOkNext = 2200;
  23.  
  24. type
  25.  
  26.   {TComboCollection}
  27.  
  28.   PComboCollection = ^TComboCollection;
  29.   TComboCollection = object(TSortedCollection)
  30.     function TxtPtr(Item : integer) : String; virtual;
  31.   end;
  32.  
  33.   {TComboListBox}
  34.  
  35.   PComboListBox = ^TComboListBox;
  36.   TComboListBox = object(TSortedListBox)
  37.     constructor Init(var Bounds : TRect; ANumCols : word;
  38.                      AScrollBar : PScrollBar);
  39.     procedure HandleEvent(var Event : TEvent); virtual;
  40.     procedure FocusItem(Item: Integer); virtual;
  41.     function GetText(Item: Integer; MaxLen: Integer): String; virtual;
  42.     function GetPalette : PPalette; virtual;
  43.   end;
  44.  
  45.   {TComboWindow}
  46.  
  47.   PComboWindow = ^TComboWindow;
  48.   TComboWindow = object(TWindow)
  49.     SelText : string;
  50.     constructor Init(var Bounds : TRect; ListPtr : PComboCollection);
  51.     constructor Load(var S : TStream);
  52.     procedure Store(var S : TStream);
  53.     procedure HandleEvent(var Event : TEvent); virtual;
  54.     function GetPalette : PPalette; virtual;
  55.   end;
  56.  
  57.   {TComboBox}
  58.  
  59.   PComboBox = ^TComboBox;
  60.   TComboBox = object(TView)
  61.     ILine        : PInputLine;
  62.     List         : PComboCollection;
  63.     ILineFocused : Boolean;
  64.  
  65.     constructor Init(var Bounds : TRect; LinePtr : PInputLine;
  66.                      ListPtr : PComboCollection);
  67.     constructor Load(var S : TStream);
  68.     procedure Store(var S : TStream);
  69.     procedure Draw; virtual;
  70.     procedure HandleEvent(var Event : TEvent); virtual;
  71.     function GetPalette: PPalette; virtual;
  72.   end;
  73.  
  74.   procedure RegisterCombo;
  75.  
  76. const
  77.   RComboCollection : TStreamRec = (
  78.     ObjType : 1000;
  79.     VmtLink : Ofs(TypeOf(TComboCollection)^);
  80.     Load    : @TComboCollection.Load;
  81.     Store   : @TComboCollection.Store
  82.   );
  83.  
  84.   RComboListBox : TStreamRec = (
  85.     ObjType : 1001;
  86.     VmtLink : Ofs(TypeOf(TComboListBox)^);
  87.     Load    : @TComboListBox.Load;
  88.     Store   : @TComboListBox.Store
  89.   );
  90.  
  91.   RComboWindow : TStreamRec = (
  92.     ObjType : 1002;
  93.     VmtLink : Ofs(TypeOf(TComboWindow)^);
  94.     Load    : @TComboWindow.Load;
  95.     Store   : @TComboWindow.Store
  96.   );
  97.  
  98.   RComboBox : TStreamRec = (
  99.     ObjType : 1003;
  100.     VmtLink : Ofs(TypeOf(TComboBox)^);
  101.     Load    : @TComboBox.Load;
  102.     Store   : @TComboBox.Store
  103.   );
  104.  
  105.  
  106. implementation
  107.  
  108. {TComboCollection}
  109. function TComboCollection.TxtPtr;
  110. begin
  111.   TxtPtr := String(At(Item)^);
  112. end;
  113.  
  114.  
  115. {TComboListBox}
  116. constructor TComboListBox.Init(var Bounds : TRect; ANumCols : word;
  117.                  AScrollBar : PScrollBar);
  118. begin
  119.   TSortedListBox.Init(Bounds, ANumCols, AScrollBar);
  120. end;
  121.  
  122. procedure TComboListBox.FocusItem(Item: Integer);
  123. begin
  124.   TSortedListbox.FocusItem(Item);
  125.   if Owner <> nil then
  126.   PComboWindow(Owner)^.SelText := PComboCollection(List)^.TxtPtr(Item);
  127. end;
  128.  
  129. function TComboListBox.GetText;
  130. var
  131.   S : string;
  132. begin
  133.   if List <> nil then
  134.   S := PComboCollection(List)^.TxtPtr(Item);
  135.   if Length(S) > MaxLen then S[0] := Char(MaxLen);
  136.   GetText := S;
  137. end;
  138.  
  139. procedure TComboListBox.HandleEvent;
  140. begin
  141.   if List=nil then exit;
  142.   if ((Event.What = evMouseDown) and (Event.Double)) or
  143.      ((Event.What = evKeyDown) and (Event.KeyCode = kbEnter)) then
  144.   begin
  145.     Event.What := evCommand;
  146.     Event.Command := cmOK;
  147.     PutEvent(Event);
  148.     ClearEvent(Event);
  149.   end
  150.   else if ((Event.What = evKeyDown) and (Event.KeyCode = kbTab)) then
  151.   begin
  152.     Event.What := evCommand;
  153.     Event.Command := cmOkNext;
  154.     PutEvent(Event);
  155.     ClearEvent(Event);
  156.   end
  157.   else TSortedListBox.HandleEvent(Event);
  158. end;
  159.  
  160. function TComboListBox.GetPalette : PPalette;
  161. const
  162.   P : string[Length(CHistoryViewer)] = CHistoryViewer;
  163. begin
  164.   GetPalette := @P;
  165. end;
  166.  
  167. {TComboWindow}
  168.  
  169. constructor TComboWindow.Init;
  170. var
  171.   sbPtr : PScrollBar;
  172.   R : TRect;
  173.   B : PComboListBox;
  174. begin
  175.   TWindow.Init(Bounds, '', wnNoNumber);
  176.   GetExtent(R); R.Grow(-1,-1);
  177.   Flags := Flags and not (wfGrow + wfMove + wfZoom);
  178.   if ListPtr<>nil then
  179.   begin
  180.     sbPtr := StandardScrollBar(sbVertical);
  181.     B := New(PComboListBox, Init(R,1, sbPtr));
  182.     B^.NewList(ListPtr);
  183.     Insert(B);
  184.     B^.FocusItem(0);
  185.   end;
  186. end;
  187.  
  188. constructor TComboWindow.Load(var S : TStream);
  189. begin
  190.   TWindow.Load(S);
  191.   S.Read(SelText, SizeOf(string));
  192. end;
  193.  
  194. procedure TComboWindow.Store(var S : TStream);
  195. begin
  196.   TWindow.Store(S);
  197.   S.Write(SelText, SizeOf(string));
  198. end;
  199.  
  200.  
  201. function TComboWindow.GetPalette : PPalette;
  202. const
  203.   P : string[Length(CHistoryWindow)] = CHistoryWindow;
  204. begin
  205.   GetPalette := @P;
  206. end;
  207.  
  208. procedure TComboWindow.HandleEvent;
  209. begin
  210.   if ((Event.What = evKeyDown) and (Event.KeyCode = kbEsc)) or
  211.      ((Event.What = evMouseDown) and (Event.Buttons = mbRightButton)) then
  212.   begin
  213.     Event.What := evCommand;
  214.     Event.Command := cmCancel;
  215.   end;
  216.   if (Event.What = evCommand) then
  217.   case Event.Command of
  218.     cmOK, cmCancel,cmOkNext :  EndModal(Event.Command);
  219.   end;
  220.   TWindow.HandleEvent(Event);
  221. end;
  222.  
  223. {TComboBox}
  224.  
  225. constructor TComboBox.Init;
  226. begin
  227.   if (LinePtr=nil) or (ListPtr=nil) then Fail;
  228.   TView.Init(Bounds);
  229.   Options := Options or ofPostProcess;
  230.   EventMask := EventMask or evBroadcast;
  231.   ILine := LinePtr;
  232.   List := ListPtr;
  233. end;
  234.  
  235. constructor TComboBox.Load(var S : TStream);
  236. begin
  237.   TView.Load(S);
  238.   GetPeerViewPtr(S, ILine);
  239.   List := PComboCollection(S.Get);
  240.   S.Read(ILineFocused, SizeOf(boolean));
  241. end;
  242.  
  243. procedure TComboBox.Store(var S : TStream);
  244. begin
  245.   TView.Store(S);
  246.   PutPeerViewPtr(S, ILine);
  247.   S.Put(List);
  248.   S.Write(ILineFocused, SizeOf(boolean));
  249. end;
  250.  
  251.  
  252. procedure TComboBox.HandleEvent;
  253. var
  254.   R,Extent : TRect;
  255.   W        : PComboWindow;
  256.   Control  : integer;
  257. begin
  258.   if (Event.What = evBroadcast) and (PInputLine(Event.InfoPtr) = ILine) then
  259.   begin
  260.     case Event.Command of
  261.       cmReceivedFocus : ILineFocused := True;
  262.       cmReleasedFocus : ILineFocused := False;
  263.     end;
  264.     ClearEvent(Event);
  265.   end;
  266.  
  267.   if (Event.What = evMouseDown) or ((Event.What = evKeyDown) and
  268.      (Event.KeyCode = kbDown) and ILineFocused) and (List^.Count>0) then
  269.   begin
  270.     if not ILineFocused then ILine^.Select;
  271.     Owner^.GetExtent(Extent);
  272.     ILine^.GetBounds(R); R.Grow(1,1); R.B.Y := Extent.B.Y - 1;
  273.     if List^.Count < (R.B.Y - R.A.Y - 1) then
  274.       R.B.Y := R.A.Y + List^.Count + 2;
  275.     W := New(PComboWindow, Init(R, List));
  276.     Control := Owner^.ExecView(W);
  277.     if Control <> cmCancel then
  278.     begin
  279.       ILine^.Data^ := W^.SelText;
  280.       ILine^.SelectAll(False);
  281.       ILine^.DrawView;
  282.     end;
  283.     Dispose(W,Done);
  284.     if Control = cmOkNext then Owner^.SelectNext(False);
  285.     ClearEvent(Event);
  286.   end
  287.   else TView.HandleEvent(Event);
  288. end;
  289.  
  290. function TComboBox.GetPalette : PPalette;
  291. const
  292.   P : string[Length(CHistory)] = CHistory;
  293. begin
  294.   GetPalette := @P;
  295. end;
  296.  
  297. procedure TComboBox.Draw;
  298. begin
  299.   WriteChar(0,0,#222,2,1);
  300.   WriteChar(1,0,#25,1,1);
  301.   WriteChar(2,0,#221,2,1);
  302. end;
  303.  
  304. procedure RegisterCombo;
  305. begin
  306.   RegisterType(RComboCollection);
  307.   RegisterType(RComboListBox);
  308.   RegisterType(RComboWindow);
  309.   RegisterType(RComboBox);
  310. end;
  311.  
  312. end. {Combo}
  313.